from BeautifulSoup import  BeautifulStoneSoup
from MovieClass import MovieClass
from CoreFunctions import GetConfig, GetSetting
import os, sqlite3, time, urllib
from CoreFunctions import LogEvents, LogEvent
class MovieDatabase():
    def __init__(self):
        self.DBName         = ""
        self.MovieFolder    = ""
        self.MovieTypes     = []
        self.Mode           = 1     #update mode
        self.OSSeperator    = "/"
           
        if GetConfig('settings.ini'):
            self.MovieFolder    = GetSetting("Common", "MovieFolder")    #"/Movies" #"c:\\temp\\temp"
            self.MovieTypes     = GetSetting("MovieDatabase", "MovieTypes")     #['avi', 'mkv', 'mp4']
            self.DBName         = GetSetting("Common", "DBName")         #"/Movies/Python/MovieDB.db"
            self.OSSeperator    = GetSetting("Common", "OSSeperator")    
            self.LogFile        = GetSetting("Common", "LogFile")
            self.ThumbsFolder   = GetSetting("MovieDatabase", "ThumbsFolder")
        self.cn = sqlite3.connect(self.DBName)
        #print "DB is %s " % self.DBName
    
    def MyTime(self):
        return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    
    def CheckDatabase(self):
        #try creating tblMovies table.
        LogEvent("Checking database")
        try:
            SQL =   "CREATE table tblMovies (MovieID integer PRIMARY KEY asc, MoviePath text DEFAULT NULL, IMDBID text UNIQUE, moviedbid text DEFAULT NULL, title text DEFAULT NULL, year text DEFAULT NULL, releasedate text DEFAULT NULL, " \
                    "rating text DEFAULT NULL, votes int DEFAULT 0, outline text DEFAULT NULL, plot text DEFAULT NULL, tagline text DEFAULT NULL , mpaa text DEFAULT NULL, certification text DEFAULT NULL, release text DEFAULT NULL, studio text DEFAULT NULL, " \
                    "country text DEFAULT NULL, language text DEFAULT NULL, genre text DEFAULT NULL, credits text DEFAULT NULL, director text DEFAULT NULL, nfo text DEFAULT NULL, nfodate text DEFAULT NULL, flag int default 0, DateAdded date DEFAULT CURRENT_TIMESTAMP, "\
                    "MovieFanart text DEFAULT NULL, MovieCover text DEFAULT NULL, VideoCODEC text DEFAULT null, VideoAspect text DEFAULT NULL, VideoWidth text DEFAULT null, VideoHeight text DEFAULT null, AudioCODEC text DEFAULT NULL, AudioChannels text DEFAULT NULL)"
            LogEvent(SQL)
            self.cursor = self.cn.execute(SQL)
        except Exception, x:
            LogEvent( x)
            
        #try creating tblACtors table.
        try:
            SQL =   "CREATE table tblActors (ActorID integer PRIMARY KEY ASC , ActorFirstName text DEFAULT NULL, ActorLastName text DEFAULT NULL, ActorThumb text DEFAULT NULL)"
            LogEvent(SQL)
            self.cursor = self.cn.execute(SQL)
        except Exception, x:
            LogEvent(x)    
            
        #try creating tblMovieActorJoiner table.
        try:
            SQL =   "CREATE table tblMovieActors (MovieActorID integer PRIMARY KEY ASC, MovieID text DEFAULT NULL, ActorID text DEFAULT NULL, ActorRole text DEFAULT NULL)"
            LogEvent(SQL)
            self.cursor = self.cn.execute(SQL)
        except Exception, x:
            LogEvent(x)     
        
        #try creating tblMovieActorJoiner table.
        try:
            SQL =   "create view vwActorMovies as select * from tblMovies inner join tblMovieActors on tblMovies.IMDBID = tblMovieActors.MovieID inner join tblActors on tblMovieActors.ActorID = tblActors.ActorID"
            LogEvent(SQL)
            self.cursor = self.cn.execute(SQL)
        except Exception, x:
            LogEvent(x)
        
        try:
            SQL =   "CREATE table tblGenres (GenreID integer PRIMARY KEY asc, Genre text UNIQUE DEFAULT NULL)"
            LogEvent(SQL)
            self.cursor = self.cn.execute(SQL)
        except Exception, x:
            LogEvent(x) 
        
        try:
            SQL =   "create view vwMovieActors as select ActorRole, ActorFirstName, ActorLastName, tblActors.ActorID, tblMovieActors.MovieID as IMDBID from tblActors inner join tblMovieActors on tblActors.ActorID = tblMovieActors.ActorID"
            LogEvent(SQL)
            self.cursor = self.cn.execute(SQL)
        except Exception, x:
            LogEvent(x) 
                    
    def ProcessFolder(self, foldername):
        LogEvent("")
        LogEvent("Processing folder " + foldername) 
        for file in os.walk(foldername):
            #file[0] = foldername
            #file[1] = 
            #file[2] = folder contents
            
            for f in file[2]:                             #iterate through the files in the folder
                LogEvent("  * read file - " + f)
                filenameparts = f.split(".")              #split the movie on .           
                if len(filenameparts)> 0:                   #is the list longer than 1 item - is there an extension?
                    try:
                        ext = filenameparts[-1:][0]
                    except AttributeError:
                        ext = filenameparts[-1:]
                    if ext.lower() in self.MovieTypes:      #is this a movie file?
                        LogEvent("")
                        LogEvent("  * movie found")
                        NewMovie = MovieClass()
                        #NewMovie.LogEvents(True, 'a', self.LogFile)
                        NewMovie.DBName = self.DBName
                        NewMovie.Connect()
                        NewMovie.Mode       = self.Mode
                        NewMovie.NFO        = self.LocateNFO(self.MakePath(file[0] , self.OSSeperator , self.MakeFilename(filenameparts[:-1])))
                        NewMovie.MoviePath  = self.CheckMultiPart(self.MakePath(file[0], self.OSSeperator, f))
                        if NewMovie.NFO!="":
                            try:
                                LogEvent("  * trying to locate NFO for movie...")
                                NewMovie.NFODate = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getmtime(NewMovie.NFO)))
                                self.GetMovieDetails(NewMovie)
                                LogEvent(NewMovie.Title)
                            except Exception, x:
                                LogEvent( x)
                        
                        NewMovie.Submit() 
                        NewMovie = None
    def CheckMultiPart(self, moviepath):
        if "[CD1]" in moviepath:
            if os.path.exists(moviepath.replace("[CD1]", "[CD2]")):
                moviepath = self.CreateJSP(moviepath)
                   
        return moviepath
    def CreateJSP(self, moviepath):
        ext = moviepath[-3:]
        moviepathstring1    = moviepath.replace(" ", "%20").replace("[", "%5B").replace("]", "%5D")
        moviepathstring2    = moviepathstring1.replace("CD1", "CD2")
        moviepath           = moviepath.replace(ext, "jsp")
        
        print "Creating playlist file " + moviepath
        JSP = open(moviepath, "w")
        JSP.write("Movie 1|0|0|file:///opt/sybhttpd/localhost.drives/NETWORK_SHARE"  + moviepathstring1 + "|\n")
        JSP.write("Movie 1|0|0|file:///opt/sybhttpd/localhost.drives/NETWORK_SHARE"  + moviepathstring2 + "|")
        JSP.close()
        print "Playlist created"
        
        
        return moviepath
        #"Zodiac 1|0|0|file:///opt/sybhttpd/localhost.drives/NETWORK_SHARE/Movies/Zodiac/Zodiac%20%5BCD1%5D.avi|"                    
    def MakePath(self, folder, OSSeperator, filename):
            if folder[-1:]!=OSSeperator:
                folder+=OSSeperator
            return folder+filename
                                    
    def GetMovieDetails(self, NewMovie):
        LogEvent("  * opening NFO - " + NewMovie.NFO)
        MovieFile = open(NewMovie.NFO,'r')
        MovieXML = ""
        for line in MovieFile:
            MovieXML += line
        if MovieXML != None:
            MovieXML = MovieXML.replace("name>", "actorname>")
            MovieXML = MovieXML.replace("id moviedb", "moviedb>")
    
            soup = BeautifulStoneSoup(MovieXML)
            
            LogEvent("  * adding movie attributes")
            NewMovie.ID             = self.GetDataFromElement(soup.findAll({'id':True}), 'id')
            NewMovie.Title          = self.GetDataFromElement(soup.findAll({'title':True}), 'title')
            NewMovie.Year           = self.GetDataFromElement(soup.findAll({'year':True}), 'year')
            NewMovie.ReleaseDate    = self.GetDataFromElement(soup.findAll({'releasedate':True}), 'releasedate')
            NewMovie.Rating         = self.GetDataFromElement(soup.findAll({'rating':True}), 'rating')
            NewMovie.Votes          = self.GetDataFromElement(soup.findAll({'votes':True}), 'votes')
            NewMovie.Outline        = self.GetDataFromElement(soup.findAll({'outline':True}), 'outline')
            NewMovie.Plot           = self.GetDataFromElement(soup.findAll({'plot':True}), 'plot')
            NewMovie.Tagline        = self.GetDataFromElement(soup.findAll({'tagline':True}), 'tagline')
            NewMovie.MPAA           = self.GetDataFromElement(soup.findAll({'mpaa':True}), 'mpaa')
            NewMovie.Certification  = self.GetDataFromElement(soup.findAll({'certification':True}), 'certification')
            NewMovie.Release        = self.GetDataFromElement(soup.findAll({'release':True}), 'release')
            NewMovie.Studio         = self.GetDataFromElement(soup.findAll({'studio':True}), 'studio')
            NewMovie.Country        = self.GetDataFromElement(soup.findAll({'country':True}), 'country')
            NewMovie.Language       = self.GetDataFromElement(soup.findAll({'language':True}), 'language')
            NewMovie.Genre          = self.GetDataFromElement(soup.findAll({'genre':True}), 'genre')
            NewMovie.Credits        = self.GetDataFromElement(soup.findAll({'credits':True}), 'credits')
            NewMovie.Director       = self.GetDataFromElement(soup.findAll({'director':True}), 'director')
            
            #media details
            VideoOutput     = soup.findAll({'videooutput':True})
            if VideoOutput:
                NewMovie.VideoOutput    = self.GetDataFromElement(VideoOutput, "videooutput")
            Video   = soup.findAll({'video':True})
            if Video:
                self.GetVideoInfo(NewMovie, Video)
            Audio   = soup.findAll({'audio':True})
            if Audio:
                self.GetAudioInfo(NewMovie, Audio)
            #Actor section
            allActs = soup.findAll({'actor':True})
            if allActs!=None:
                LogEvent("  * there are actors for this movie...")
                NewMovie.Actors = self.GetActors(allActs) 
                #NewMovie.GetActors()
                            
    def GetDataFromElement(self, theelements, tag):
        element = ""
        if theelements!=None:
            for theelement in theelements:
                theelement = BeautifulStoneSoup(unicode(theelement)) 
                if theelement!=None:
                    element=unicode(theelement.contents[0]).replace("<" + tag + ">", "").replace("</" + tag + ">","")
                    element=element.replace(chr(34), "'")

        return element
        
    def LocateNFO(self, file):        
            nfofile       = ""
            nfofiletmp    = file + "nfo"
            #print " - looking for %s" % moviefiletmp
            
            if os.path.exists(nfofiletmp):            #look for a .avi first as we prefer a .mkv
                #print "  - found  - %s " % moviefiletmp
                nfofile = nfofiletmp
            if "[CD1]" in nfofiletmp:
                nfofiletmp = nfofiletmp.replace(" [CD1]", "").replace("[CD1]", "")
                if os.path.exists(nfofiletmp):            #look for a .avi first as we prefer a .mkv
                    nfofile = nfofiletmp
                    
            return nfofile
                        
                        
    def MakeFilename(self, filenamebits):
        x = len(filenamebits)
        filename = ""

        y = 0
        while y < x:
            filename+=filenamebits[y]+"."
            y+=1
        return filename
    
    def GetVideoInfo(self, NewMovie, VideoTag):
        for v in VideoTag:
            VideoItem = BeautifulStoneSoup(unicode(v))     
            try:
                NewMovie.VideoCODEC         = unicode(VideoItem.codec.contents[0])
            except Exception, x:
                LogEvent("Error retrieving video info: " + unicode(x)) 
                NewMovie.VideoCODEC = ""
            try:         
                NewMovie.VideoAspect         = unicode(VideoItem.aspect.contents[0])
            except Exception, x:
                LogEvent("Error retrieving video info: " + unicode(x)) 
                NewMovie.VideoAspect = ""
            try:    
                NewMovie.VideoWidth          = unicode(VideoItem.width.contents[0])
            except Exception, x:
                LogEvent("Error retrieving video info: " + unicode(x)) 
                NewMovie.VideoWidth = ""
            try:    
                NewMovie.VideoHeight         = unicode(VideoItem.height.contents[0])
            except Exception, x:
                LogEvent("Error retrieving video info: " + unicode(x))
                NewMovie.VideoHeight = ""
                
    def GetAudioInfo(self, NewMovie, AudioTag):
        for a in AudioTag:
            AudioItem = BeautifulStoneSoup(unicode(a))     
            try:
                NewMovie.AudioChannels  = unicode(AudioItem.channels.contents[0])
            except Exception, x:
                LogEvent("Error retrieving video info: " + unicode(x))  
                NewMovie.AudioChannels = ""
            try:    
                NewMovie.AudioCODEC     = unicode(AudioItem.codec.contents[0])
            except Exception, x:
                LogEvent("Error retrieving video info: " + unicode(x))     
                NewMovie.AudioCODEC = ""
                                 
    def GetActors(self, actortag):
        Actors = {}
        try:
            for x in actortag:
                xmlActor = BeautifulStoneSoup(unicode(x))
                try:
                    if Actors.has_key(xmlActor.actorname.contents[0]) == False:
                        Actors[xmlActor.actorname.contents[0]] = []
                    Actors[xmlActor.actorname.contents[0]].append(xmlActor.role.contents[0])
                    Actors[xmlActor.actorname.contents[0]].append(xmlActor.thumb.contents[0])
                    LogEvent("Actor name is : " + xmlActor.actorname.contents[0])
                    LogEvent("Actor role is : " + xmlActor.role.contents[0])
                    LogEvent("Actor thumb is : " + xmlActor.thumb.contents[0])
                    try:
                        urllib.urlretrieve(xmlActor.thumb.contents[0], self.ThumbsFolder + self.OSSeperator + xmlActor.thumb.contents[0].split("/")[-1:][0] )
                    except Exception, x:
                        LogEvent("Error downloading actor thumbnail: " + str(x))

                except Exception, x:
                    LogEvent("Error retrieving actor info: " + (x))
            
        except Exception, x:
            LogEvent(x)
        finally:
            return Actors
        

if __name__ == "__main__":
    MyMovies = MovieDatabase()
    LogEvents('a', MyMovies)
    LogEvent("Started at " + MyMovies.MyTime())
    print "Started at " + MyMovies.MyTime()
    MyMovies.CheckDatabase()
    MyMovies.Mode = 2   #1 is the default which is updated chnged NFOs and add new 
    MyMovies.ProcessFolder(MyMovies.MovieFolder)
    print "Finished at " + MyMovies.MyTime()
    